package com.gdufe.mistakebook.controller;

import com.gdufe.mistakebook.entity.vo.count.CreateTimeQuestionCountVO;
import com.gdufe.mistakebook.entity.vo.count.LabelQuestionCountVO;
import com.gdufe.mistakebook.entity.vo.count.PriorityQuestionCountVO;
import com.gdufe.mistakebook.entity.vo.count.SubjectQuestionCountVO;
import com.gdufe.mistakebook.entity.dto.QueryQuestionsDto;
import com.gdufe.mistakebook.entity.dto.QuestionDTO;
import com.gdufe.mistakebook.entity.vo.QueryQuestionsVo;
import com.gdufe.mistakebook.entity.vo.QuestionVO;
import com.gdufe.mistakebook.exception.BusinessException;
import com.gdufe.mistakebook.result.PageResult;
import com.gdufe.mistakebook.result.Result;
import com.gdufe.mistakebook.service.QuestionService;
import com.gdufe.mistakebook.util.MistakeBookUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
 * @author lzh
 */
@RestController
@RequestMapping("/question")
@Slf4j(topic = "QuestionController.class")
@CrossOrigin
public class QuestionController {

    @Value("${mistakebook.path.upload}")
    private String uploadPath;

    @Value("${mistakebook.path.domain}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Resource
    private QuestionService questionService;

    /**
     * 条件分页查询错题
     *
     * @param queryQuestionsDto 查询参数
     * @return 分页结果
     */
    @GetMapping("/list")
    public Result<PageResult> listQuestions(QueryQuestionsDto queryQuestionsDto) {
        if (queryQuestionsDto == null) {
            throw new BusinessException(0, "参数不能为空");
        }
        PageResult pageResult = questionService.pageQuestions(queryQuestionsDto);
        return Result.success(pageResult);
    }

    /**
     * 错题随机练习
     *
     * @param count 随机联系 错题数目
     */
    @GetMapping("/random")
    public Result<PageResult> randomQuestions(Integer count) {
        if (count == null) {
            throw new BusinessException(0, "参数不能为空");
        }
        if (count < 0) {
            throw new BusinessException(0, "参数不合法");
        }
        List<QueryQuestionsVo> questionsVos = questionService.randomQuestions(count);
        return Result.success(new PageResult(questionsVos.size(), questionsVos));
    }


    /**
     * 处理图片文件上传
     *
     * @param questionImage 图片
     * @return 图片所在路径
     */
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile questionImage) {
        if (questionImage == null) {
            throw new BusinessException(0, "图片还未上传!");
        }
        // 获取文件名
        String fileName = questionImage.getOriginalFilename();
        if (fileName == null) {
            throw new BusinessException(0, "文件上传出错!");
        }
        // 获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        if (StringUtils.isBlank(suffix)) {
            throw new BusinessException(0, "文件格式不正确!");
        }
        // 生成随机文件名
        fileName = MistakeBookUtil.generateUUID() + suffix;
        // 确定存放图片路径
        File dest = new File(uploadPath + "/" + fileName);
        try {
            // 存放图片
            questionImage.transferTo(dest);
            // 获取当前图片访问路径
            String imageUrl = domain + contextPath + "/question/image/" + fileName;
            return Result.success(imageUrl);
        } catch (IOException e) {
            log.error("上传图片失败：{}", e.getMessage());
            throw new BusinessException(0, "上传文件失败、服务器发生异常!");
        }
    }

    /**
     * 获取错题图片
     *
     * @param fileName 图片名
     * @param response 响应结果
     */
    @GetMapping("/image/{fileName}")
    public void getQuestionImage(@PathVariable("fileName") String fileName, HttpServletResponse response) {
        // 确定文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        // 确定服务器存放路径
        fileName = uploadPath + "/" + fileName;
        // 响应图片
        // 确定图片响应类型
        response.setContentType("image" + suffix);
        try (
                OutputStream os = response.getOutputStream();
                FileInputStream fileInputStream = new FileInputStream(fileName)
        ) {
            byte[] buffer = new byte[1024];
            int b;
            while ((b = fileInputStream.read(buffer)) != -1) {
                os.write(buffer, 0, b);
            }
        } catch (IOException e) {
            log.error("获取错题图片失败：{}", e.getMessage());
            throw new BusinessException(0, "错题图片展现失败!");
        }
    }

    /**
     * 新增错题
     *
     * @param questionDto 错题新增DTO
     * @return 返回新增结果
     */
    @PostMapping
    public Result<String> insertQuestion(@RequestBody QuestionDTO questionDto) {
        if (questionDto == null) {
            throw new BusinessException(0, "添加错题异常!");
        }
        log.warn("新增错题：{}", questionDto);
        questionService.insertQuestionWithLabel(questionDto);
        return Result.success("新增错题成功，快去看看吧!");
    }

    @PutMapping
    public Result<String> updateQuestion(@RequestBody QuestionDTO questionDto) {
        if (questionDto == null) {
            throw new BusinessException(0, "更改错题异常!");
        }
        log.warn("修改错题：{}", questionDto);

        questionService.updateQuestionWithLabel(questionDto);

        return Result.success("修改成功!");
    }

    @DeleteMapping("/status/{status}")
    public Result<String> deleteQuestion(@PathVariable("status") Integer status, Integer questionId) {

        log.warn("删除错题：{}, {}", questionId, status);
        questionService.deleteQuestionWithLabel(status, questionId);
        return Result.success("删除成功!");
    }

    /**
     * 根据id获取错题详情
     */
    @GetMapping("/{id}")
    public Result<QuestionVO> getDetails(@PathVariable("id") Integer id) {
        log.warn("查询错题详情：{}", id);
        QuestionVO questionVO = questionService.getDetails(id);
        return Result.success(questionVO);
    }

    /**
     * 统计各种学科对应的错题数量
     */
    @GetMapping("/subjectCount")
    public Result getSubjectAmount() {
        List<SubjectQuestionCountVO> sqcList = questionService.getSubjectAmount();
        return Result.success(sqcList);
    }

    /**
     * 统计各类标签对应的错题数量
     */
    @GetMapping("/labelCount")
    public Result getLabelAmount() {
        List<LabelQuestionCountVO> lqcList = questionService.getLabelAmount();
        return Result.success(lqcList);
    }
    /**
     * 统计优先级对应的错题数量
     */
    @GetMapping("/priorityCount")
    public Result getPriorityAmount() {
        List<PriorityQuestionCountVO> pqcList = questionService.getPriorityAmount();
        return Result.success(pqcList);
    }

    /**
     * 统计时间对应的错题数量
     */
    @GetMapping("/createTimeCount")
    public Result getCreateTimeAmount() {
        List<CreateTimeQuestionCountVO> ctqcList = questionService.getCeateTimeAmount();
        return Result.success(ctqcList);
    }

}
